<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>使用canvas 绘图</title>
    <style>
        div {
            display: inline-block;
        }

        canvas {
            background-color: #f1f1f1
        }
    </style>
</head>

<body>
    <p>使用canvas绘图</p>
    <div>
        <canvas id="drawing" width="200" height="200">
            使用canvas绘图
        </canvas>
    </div>
    <div>
        <canvas id="drawing2" width="200" height="200">
            使用canvas绘图
        </canvas>
    </div>
    <div>
        <canvas id="drawing3" width="200" height="200">
            使用canvas绘图
        </canvas>
    </div>
    <div>
        <canvas id="drawing4" width="200" height="200">
            使用canvas绘图
        </canvas>
    </div>
    <div>
        <canvas id="drawing5" width="200" height="200">
            使用canvas绘图
        </canvas>
    </div>
    <div>
        <canvas id="drawing6" width="200" height="200">
            使用canvas绘图
        </canvas>
    </div>
</body>
<script>
    //stroke 描边
    (function () {
        var drawing = document.getElementById("drawing");
        // 确定浏览器是否支持canvas元素
        if (drawing.getContext) {
            var context = drawing.getContext("2d");

            // 4个参数 (x,y)在canvas画布上的坐标  以及矩形的宽高 单位都是px
            // 先指定strokeStyle 再指定strokeRect  否则后指定的strokeStyle无效
            context.strokeStyle = "#ff0000";
            context.strokeRect(10, 10, 50, 50);

            context.strokeStyle = "rgba(0,0,255,0.5)";
            context.strokeRect(30, 30, 50, 50);

            // 线条的宽度 任意整数
            context.lineWidth = 5;
            // 线条末端的形状  butt 平头 round 圆头 square 方头
            context.lineCap = "butt";
            // 线条相交的方式 round 圆交 bevel 斜交 miter 斜接
            context.lineJoin = "round";

            // 取得图像的数据URL
            var imgURL = drawing.toDataURL("image/png");

            // 显示图像
            var image = document.createElement("img");
            image.src = imgURL;
            document.body.appendChild(image);
        }
    })();
    //fill 填充
    (function () {
        var drawing = document.getElementById("drawing2");
        // 确定浏览器是否支持canvas元素
        if (drawing.getContext) {
            var context = drawing.getContext("2d");

            // 4个参数 (x,y)在canvas画布上的坐标  以及矩形的宽高 单位都是px
            context.fillStyle = "#ff0000";
            context.fillRect(10, 10, 50, 50);

            context.fillStyle = "rgba(0,0,255,0.5)";
            context.fillRect(30, 30, 50, 50);
        }
    })();
    //clearRect 清除画布上的矩形区域
    (function () {
        var drawing = document.getElementById("drawing3");
        // 确定浏览器是否支持canvas元素
        if (drawing.getContext) {
            var context = drawing.getContext("2d");

            // 4个参数 (x,y)在canvas画布上的坐标  以及矩形的宽高 单位都是px
            context.fillStyle = "#ff0000";
            context.fillRect(10, 10, 50, 50);

            context.fillStyle = "rgba(0,0,255,0.5)";
            context.fillRect(30, 30, 50, 50);

            // 4个参数 (x,y)在canvas画布上的坐标  以及矩形的宽高 单位都是px
            // 这个方法可以把绘制上下文中的某个矩形区域变透明
            // 通过绘制形状然后再清除指定区域，就可以生成有意思的效果，例如把某个形状中间去掉一块
            context.clearRect(40, 40, 10, 10)
        }
    })();
    //绘制路径、文本 
    (function () {
        var drawing = document.getElementById("drawing4");
        // 确定浏览器是否支持canvas元素
        if (drawing.getContext) {
            var context = drawing.getContext("2d");

            // 开始绘制路径前必须调用 开始路径
            context.beginPath();

            // 绘制外圆
            // 圆心(100,100) 半径99 从0度画到360度 顺时针
            context.arc(100, 100, 99, 0, 2 * Math.PI, false);

            // 绘制另一个路径前 必须将绘图游标移动到内圆或路径上的某一点 以避免绘制出多余的线条
            context.moveTo(194, 100);
            // 绘制内圆
            // 圆心(100,100) 半径94 从0度画到360度 顺时针
            context.arc(100, 100, 94, 0, 2 * Math.PI, false);

            // 将绘图游标移动到100,100
            context.moveTo(100, 100);
            // 画一条线到 坐标(100,15)处
            context.lineTo(100, 15);

            // 将绘图游标移动到100,100
            context.moveTo(100, 100);
            // 画一条线到 坐标(35,100)处
            context.lineTo(35, 100);

            // 绘制文本
            // 文本水平中心在x坐标点位置
            // 文本基线 文本的垂直中心位于y坐标
            context.font = "bold 14px Arial";
            context.textAlign = "center";
            context.textBaseline = "middle";

            //4个参数 绘制的文本 在画布中的坐标点 以及可选的文本最大像素值
            context.fillText('12', 100, 20);

            // 文本开头在x坐标点位置
            // 文本基线 文本的头部中心位于y坐标
            context.textAlign = "start";
            context.textBaseline = "top";
            context.fillText('12', 100, 40);

            // 文本末尾在x坐标点位置
            // 文本基线 文本的底部中心位于y坐标
            context.textAlign = "end";
            context.textBaseline = "bottom";
            context.fillText('12', 100, 60);

            // 调用stroke()方法 这样才能把图形绘制到画布上
            context.stroke();
        }
    })();
    //变换
    (function () {
        var drawing = document.getElementById("drawing5");
        // 确定浏览器是否支持canvas元素
        if (drawing.getContext) {
            var context = drawing.getContext("2d");

            // 开始绘制路径前必须调用 开始路径
            context.beginPath();

            // 绘制外圆
            // 圆心(100,100) 半径99 从0度画到360度 顺时针
            context.arc(100, 100, 99, 0, 2 * Math.PI, false);

            // 绘制另一个路径前 必须将绘图游标移动到内圆或路径上的某一点 以避免绘制出多余的线条
            context.moveTo(194, 100);
            // 绘制内圆
            // 圆心(100,100) 半径94 从0度画到360度 顺时针
            context.arc(100, 100, 94, 0, 2 * Math.PI, false);

            // 将原点(0,0) 改变到(100,100);
            // 即之后的原点(0,0)代表着(100,100);
            context.translate(100, 100);

            // 旋转原点 因为原点改变了 所以只旋转之后的原点上的内容
            // 所以看起来像表针在旋转
            context.rotate(1)

            // 将绘图游标移动到0,0,实质上是移到原来的100,100
            context.moveTo(0, 0);
            // 画一条线到 坐标(0,-85)处
            context.lineTo(0, -85);

            // 再次移动到0,0
            context.moveTo(0, 0);
            // 画一条线到 坐标(-65,0)处
            context.lineTo(-65, 0);

            // 调用stroke()方法 这样才能把图形绘制到画布上
            context.stroke();
        }
    })();
    //使用save()、restore() 
    // 可以把当时的设置进入一个栈结构、得以保存，然后可以对上下文进行修改
    // 等想要回到之前保存的设置时就可以调用restore()
    // 保存在栈结构中设置就会向前返回一级
    // 连续调用save()可以把更多设置保存在栈结构中，之后再连续调用restore()则可以一级一级的返回

    // 注意 save()方法保存的只是对绘图上下文的设置和变换，并不会保存绘图上下文的内容,
    // 所以之前的已经绘图的内容不会变，只是把之前的设置还原，应用到后面的绘图内容
    (function () {
        var drawing = document.getElementById("drawing6");
        // 确定浏览器是否支持canvas元素
        if (drawing.getContext) {
            var context = drawing.getContext("2d");

            // 4个参数 (x,y)在canvas画布上的坐标  以及矩形的宽高 单位都是px
            context.fillStyle = "red";//填充为红色
            context.save();//保存设置1

            context.fillStyle="green";//填充为绿色
            context.translate(100,100)//变换原点到100,100处
            context.save();//保存设置2

            context.fillStyle = "blue";//填充为蓝色
            context.fillRect(0,0,50,50);// 在100,100处绘制一个蓝色的矩形 

            context.restore();//返回上一级设置 2 在设置2中 应填充为绿色 且原点变换在100,100
            context.fillRect(10, 10, 50,50);// 所以在110,110处绘制一个绿色的矩形

            context.restore();//再返回上一级设置1 应填充为红色 没有变换原点 
            context.fillRect(20, 20, 50,50);// 所以在20,20 处绘制一个红色的矩形
        }
    })();
</script>

</html>